// Copyright 2006 Bret Taylor
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

#ifndef INDIE_ASTPRINTER_H__
#define INDIE_ASTPRINTER_H__

#include <iostream>

#include "visitor.h"

using std::ostream;

namespace indie {

class AstPrinter : private Visitor {
  public:
    AstPrinter();
    virtual ~AstPrinter();

    void Print(const Ast& ast, ostream& stream);

  private:
    virtual void Enter(const AstClassType& ast);
    virtual void Enter(const AstArrayType& ast);
    virtual void Enter(const AstUnionType& ast);
    virtual void Enter(const AstVariable& ast);
    virtual void Enter(const AstMethod& ast);
    virtual void Enter(const AstClass& ast);
    virtual void Enter(const AstFile& ast);
    virtual void Enter(const AstBlockStatement& ast);
    virtual void Enter(const AstExpressionStatement& ast);
    virtual void Enter(const AstAssignment& ast);
    virtual void Enter(const AstVariableDeclaration& ast);
    virtual void Enter(const AstEmptyStatement& ast);
    virtual void Enter(const AstIf& ast);
    virtual void Enter(const AstWhile& ast);
    virtual void Enter(const AstFor& ast);
    virtual void Enter(const AstBreak& ast);
    virtual void Enter(const AstReturn& ast);
    virtual void Enter(const AstParenthesizedExpression& ast);
    virtual void Enter(const AstAccess& ast);
    virtual void Enter(const AstArrayAccess& ast);
    virtual void Enter(const AstBinaryExpression& ast);
    virtual void Enter(const AstUnaryExpression& ast);
    virtual void Enter(const AstCall& ast);
    virtual void Enter(const AstNewInstance& ast);
    virtual void Enter(const AstNewArray& ast);
    virtual void Enter(const AstTypeTest& ast);
    virtual void Enter(const AstThis& ast);
    virtual void Enter(const AstIntegerConstant& ast);
    virtual void Enter(const AstStringConstant& ast);
    virtual void Enter(const AstFloatConstant& ast);
    virtual void Enter(const AstBooleanConstant& ast);

    virtual void LeaveDefault(const Ast& ast);

    void PrintNode(const char* node_type);

    ostream* stream_;
    unsigned int num_tabs_;
};

} // namespace indie

#endif // INDIE_ASTPRINTER_H__
